﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Input;
using System.Windows.Controls;

namespace RouteTest
{
    public class EdgeShape
    {
        public stEdge _Edge = new stEdge();
        public Line _Line = new Line();
        public Ellipse _Arrow = new Ellipse();
        public Label _Label = new Label();
        private Canvas _Parent;

        public enumDrawEdgeStatus _DrawStatus;

        public EdgeShape(stEdge edge, Canvas parent)
        {
            _Parent = parent;

            _Edge = edge;

            _Label.Content = _Edge.distance.ToString();
            _Label.Width =25;
            _Label.Height = 20;
            _Label.FontSize= 8;

            _Label.HorizontalAlignment = HorizontalAlignment.Center;
            _Label.VerticalAlignment = VerticalAlignment.Center;

            _Line.X1 = _Edge.source.position.X;
            _Line.Y1 = _Edge.source.position.Y;
            _Line.X2 = _Edge.source.position.X;
            _Line.Y2 = _Edge.source.position.Y;

            _Line.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            _Line.StrokeStartLineCap = PenLineCap.Triangle;
            _Line.StrokeEndLineCap = PenLineCap.Flat;
            _Line.StrokeThickness = 3;

            _Arrow.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            _Arrow.Fill= new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            _Arrow.Width = 10;
            _Arrow.Height= 10;
            //_Arrow.StrokeStartLineCap = PenLineCap.Triangle;
            //_Arrow.StrokeEndLineCap = PenLineCap.Flat;
            _Arrow.StrokeThickness = 3;
            System.Diagnostics.Debug.WriteLine("Math.Abs(_Line.X1 - _Line.X2) : " + Math.Abs(_Line.X1 - _Line.X2));
            System.Diagnostics.Debug.WriteLine("Math.Abs(_Line.Y1 - _Line.Y2) : " + Math.Abs(_Line.Y1 - _Line.Y2));

            double x = Math.Abs(_Line.X2 - _Line.X1);
            double y = Math.Abs(_Line.Y2 - _Line.Y1);
            if (x == 0)
            {
                _Label.Content = "0";
            }
            else
            {
                _Edge.distance = Convert.ToInt32(Math.Sqrt((y*y) + (x*x)));
                _Label.Content = _Edge.distance.ToString();
                System.Diagnostics.Debug.WriteLine("Math.Tan(y / x) : " + Math.Tan(y / x));
            }

            _Line.MouseEnter += new MouseEventHandler(_Line_MouseEnter);
            _Line.MouseMove += new MouseEventHandler(_Line_MouseMove);
            _Line.MouseLeave += new MouseEventHandler(_Line_MouseLeave);
            _Line.MouseDown += new MouseButtonEventHandler(_Line_MouseDown);
        }

        void _Line_MouseEnter(object sender, MouseEventArgs e)
        {
            Selected();
        }

        void _Line_MouseLeave(object sender, MouseEventArgs e)
        {
            UnSelected();
        }

        void _Line_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.RightButton == MouseButtonState.Pressed)
            {

            }
        }

        public void Selected()
        {
            _Line.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            _Arrow.Stroke = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            _Arrow.Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
            System.Diagnostics.Debug.WriteLine("Edge 선택 설정");
        }

        public void UnSelected()
        {
            _Line.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            _Arrow.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            _Arrow.Fill = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            _Label.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 0, 0));
            System.Diagnostics.Debug.WriteLine("Edge 선택 해제");

        }

        void _Line_MouseMove(object sender, MouseEventArgs e)
        {
            //if (e.RightButton == MouseButtonState.Pressed)
            //{
            //    _Line.X2 = e.GetPosition(_Parent).X;
            //    _Line.Y2 = e.GetPosition(_Parent).Y;
                 
            //    Canvas.SetLeft(_Label, _Line.X1 - (((_Line.X1 - _Line.X2)) / 2));
            //    Canvas.SetTop(_Label, _Line.Y1 - (((_Line.Y1 - _Line.Y2)) / 2));

            //    System.Diagnostics.Debug.WriteLine("Edge 오른쪽 클릭 후 움직임");
            //}
        }

        public enum enumNodeType
        {
            Source,
            Dest,
        }

        int OFFSET = 15;
        public void CalLinePosition(enumNodeType type)
        {
            if (type == enumNodeType.Source)
            {
                if (_Line.X2 > _Line.X1)
                    _Line.X1 += OFFSET;
                else
                    _Line.X1 -= OFFSET;

                if (_Line.Y2 > _Line.Y1)
                    _Line.Y1 += OFFSET;
                else
                    _Line.Y1 -= OFFSET;
            }
            else
            {
                if (_Line.X2 > _Line.X1)
                    _Line.X2 -= OFFSET;
                else
                    _Line.X2 += OFFSET;

                if (_Line.Y2 > _Line.Y1)
                    _Line.Y2 -= OFFSET;
                else
                    _Line.Y2 += OFFSET;                

                double degree = ( Math.Atan2(_Line.Y2 - _Line.Y1, _Line.X2 - _Line.X1))* (180/Math.PI);
                System.Diagnostics.Debug.WriteLine("degree = " + degree.ToString());
            }
        }

        public void SetDest(NodeShape node)
        {
            _Line.X2 = node._Node.position.X;
            _Line.Y2 = node._Node.position.Y;

            CalLinePosition(enumNodeType.Source);
            CalLinePosition(enumNodeType.Dest);
            
            _Edge.dest = node._Node;

            double x = Math.Abs(_Line.X2 - _Line.X1);
            double y = Math.Abs(_Line.Y2 - _Line.Y1);

            _Edge.distance = CalDiatance();

            Canvas.SetLeft(_Label, _Line.X1-(((_Line.X1 - _Line.X2)) / 2));
            Canvas.SetTop(_Label, _Line.Y1-(((_Line.Y1 - _Line.Y2)) / 2));

            Canvas.SetLeft(_Arrow, _Line.X2 - (_Arrow.Width/2));
            Canvas.SetTop(_Arrow, _Line.Y2 - (_Arrow.Height / 2));

            _Label.Content = _Edge.distance;

            _DrawStatus = enumDrawEdgeStatus.Finish;
            System.Diagnostics.Debug.WriteLine("SetDest");
        }

        public int CalDiatance()
        {
            double x = Math.Abs(_Line.X2 - _Line.X1);
            double y = Math.Abs(_Line.Y2 - _Line.Y1);

            return Convert.ToInt32(Math.Sqrt((y * y) + (x * x)));
        }

        public void MoveSource(double x, double y)
        {
            _Line.X1 = x;
            _Line.Y1 = y;
            CalLinePosition(enumNodeType.Source);

            Canvas.SetLeft(_Label, _Line.X1 - (((_Line.X1 - _Line.X2)) / 2));
            Canvas.SetTop(_Label, _Line.Y1 - (((_Line.Y1 - _Line.Y2)) / 2));
            
            _Edge.distance = CalDiatance();
            _Label.Content = _Edge.distance;
        }

        public void MoveDest(double x, double y)
        {
            _Line.X2 = x;
            _Line.Y2 = y;
            CalLinePosition(enumNodeType.Dest);

            Canvas.SetLeft(_Label, _Line.X1 - (((_Line.X1 - _Line.X2)) / 2));
            Canvas.SetTop(_Label, _Line.Y1 - (((_Line.Y1 - _Line.Y2)) / 2));
            Canvas.SetLeft(_Arrow, _Line.X2 - (_Arrow.Width / 2));
            Canvas.SetTop(_Arrow, _Line.Y2 - (_Arrow.Height / 2));

            _Edge.distance = CalDiatance();
            _Label.Content = _Edge.distance;

        }
    }

    public class EdgeShapeList : List<EdgeShape>
    {
        Canvas _Parent;
        public bool _IsStartDraw=false;

        public EdgeShapeList(Canvas parent)
        {
            _Parent = parent;
        }

        public void SelectEdge(int id)
        {

        }

        public void AddEdge(EdgeShape edge)
        {
            this.Add(edge);

            _Parent.Children.Add(this[this.Count - 1]._Line);
            _Parent.Children.Add(this[this.Count - 1]._Arrow);
            _Parent.Children.Add(this[this.Count - 1]._Label);
        }

        public int GetDrawingEdgeID()
        {
            foreach (EdgeShape edge in this)
            {
                if (edge._DrawStatus == enumDrawEdgeStatus.Start)
                {
                    return edge._Edge.id;
                }
            }

            return -1;
        }
        public int IsOnMouseOver()
        {
            foreach (EdgeShape edge in this)
            {
                if (edge._Line.IsMouseOver)
                    return edge._Edge.id;
            }
            return -1;
        }

        public void AllUnselected()
        {
            for (int i = 0; i < this.Count; i++)
            {
                this[i].UnSelected();
            }
        }

        public void SelectEdges(int[] edges)
        {
            AllUnselected();

            for (int k = 0; k < edges.Length; k++)
            {
                if (k == edges.Length - 1)
                    break;
                for (int i = 0; i < this.Count; i++)
                {
                    if (this[i]._Edge.source.id == edges[k] && this[i]._Edge.dest.id == edges[k + 1])
                    {
                        this[i].Selected();
                        break;
                    }
                }
            }
        }
    }
}
